#ifndef PLUGINMANAGER_H
#define PLUGINMANAGER_H

#include <QObject>
#include <QMap>
#include <QStringList>
#include <QPluginLoader>
#include <QDir>

/**
 * @brief 插件接口类
 * 所有插件必须实现此接口
 */
class MarkdownPlugin : public QObject
{
    Q_OBJECT

public:
    /**
     * @brief 插件类型枚举
     */
    enum PluginType {
        ExportPlugin,    // 导出插件
        ImportPlugin,    // 导入插件
        ToolPlugin,      // 工具插件
        EditorPlugin,    // 编辑器插件
        UnknownPlugin    // 未知类型
    };
    Q_ENUM(PluginType)

    explicit MarkdownPlugin(QObject *parent = nullptr) : QObject(parent) {}
    ~MarkdownPlugin() override = default;

    /**
     * @brief 初始化插件
     * @param args 初始化参数
     * @return 成功返回true
     */
    virtual bool initialize(const QVariantMap &args) = 0;

    /**
     * @brief 获取插件名称
     * @return 插件名称
     */
    virtual QString name() const = 0;

    /**
     * @brief 获取插件显示名称
     * @return 显示名称
     */
    virtual QString displayName() const = 0;

    /**
     * @brief 获取插件描述
     * @return 插件描述
     */
    virtual QString description() const = 0;

    /**
     * @brief 获取插件版本
     * @return 版本字符串（x.y.z格式）
     */
    virtual QString version() const = 0;

    /**
     * @brief 获取插件类型
     * @return 插件类型
     */
    virtual PluginType type() const = 0;

    /**
     * @brief 获取插件作者
     * @return 作者名称
     */
    virtual QString author() const = 0;

    /**
     * @brief 检查插件是否已初始化
     * @return 已初始化返回true
     */
    virtual bool isInitialized() const = 0;

    /**
     * @brief 获取插件支持的操作
     * @return 操作名称列表
     */
    virtual QStringList supportedOperations() const = 0;

    /**
     * @brief 执行插件操作
     * @param operation 操作名称
     * @param params 操作参数
     * @return 操作结果
     */
    virtual QVariant performOperation(const QString &operation, const QVariantMap &params) = 0;

signals:
    /**
     * @brief 插件状态变化信号
     * @param message 状态消息
     * @param progress 进度（0-100，-1表示不确定）
     */
    void statusChanged(const QString &message, int progress = -1);

    /**
     * @brief 操作完成信号
     * @param operation 操作名称
     * @param success 是否成功
     * @param result 操作结果
     */
    void operationCompleted(const QString &operation, bool success, const QVariant &result);
};

// 定义插件接口ID
#define MarkdownPlugin_iid "com.markdowneditor.MarkdownPlugin"
Q_DECLARE_INTERFACE(MarkdownPlugin, MarkdownPlugin_iid)

/**
 * @brief 插件管理器
 * 负责插件的加载、管理和卸载
 */
class PluginManager : public QObject
{
    Q_OBJECT

public:
    explicit PluginManager(QObject *parent = nullptr);
    ~PluginManager() override;

    /**
     * @brief 初始化插件管理器
     * @param pluginsDir 插件目录
     * @param enabledPlugins 启用的插件列表
     * @return 成功返回true
     */
    bool initialize(const QString &pluginsDir, const QStringList &enabledPlugins);

    /**
     * @brief 加载所有可用插件
     */
    void loadPlugins();

    /**
     * @brief 加载指定插件
     * @param pluginPath 插件路径
     * @return 成功返回true
     */
    bool loadPlugin(const QString &pluginPath);

    /**
     * @brief 卸载指定插件
     * @param pluginName 插件名称
     * @return 成功返回true
     */
    bool unloadPlugin(const QString &pluginName);

    /**
     * @brief 卸载所有插件
     */
    void unloadAllPlugins();

    /**
     * @brief 启用插件
     * @param pluginName 插件名称
     */
    void enablePlugin(const QString &pluginName);

    /**
     * @brief 禁用插件
     * @param pluginName 插件名称
     */
    void disablePlugin(const QString &pluginName);

    /**
     * @brief 检查插件是否已加载
     * @param pluginName 插件名称
     * @return 已加载返回true
     */
    bool isPluginLoaded(const QString &pluginName) const;

    /**
     * @brief 检查插件是否启用
     * @param pluginName 插件名称
     * @return 已启用返回true
     */
    bool isPluginEnabled(const QString &pluginName) const;

    /**
     * @brief 获取已加载的插件列表
     * @return 插件名称列表
     */
    QStringList loadedPlugins() const;

    /**
     * @brief 获取已启用的插件列表
     * @return 插件名称列表
     */
    QStringList enabledPlugins() const;

    /**
     * @brief 获取所有可用插件（已发现的）
     * @return 插件名称列表
     */
    QStringList availablePlugins() const;

    /**
     * @brief 获取插件信息
     * @param pluginName 插件名称
     * @return 插件元数据
     */
    QVariantMap getPluginInfo(const QString &pluginName) const;

    /**
     * @brief 获取插件实例
     * @param pluginName 插件名称
     * @return 插件实例，若不存在则返回nullptr
     */
    MarkdownPlugin *getPlugin(const QString &pluginName) const;

    /**
     * @brief 获取指定类型的插件
     * @param type 插件类型
     * @return 插件名称列表
     */
    QStringList getPluginsByType(MarkdownPlugin::PluginType type) const;

    /**
     * @brief 执行插件操作
     * @param pluginName 插件名称
     * @param operation 操作名称
     * @param params 操作参数
     * @return 操作结果
     */
    QVariant performPluginOperation(const QString &pluginName, const QString &operation, const QVariantMap &params);

    /**
     * @brief 设置插件目录
     * @param dir 目录路径
     */
    void setPluginsDirectory(const QString &dir);

    /**
     * @brief 获取插件目录
     * @return 目录路径
     */
    QString pluginsDirectory() const { return m_pluginsDir; }

signals:
    /**
     * @brief 插件加载完成信号
     * @param pluginName 插件名称
     */
    void pluginLoaded(const QString &pluginName);

    /**
     * @brief 插件卸载完成信号
     * @param pluginName 插件名称
     */
    void pluginUnloaded(const QString &pluginName);

    /**
     * @brief 插件状态变化信号
     * @param pluginName 插件名称
     * @param message 状态消息
     */
    void pluginStatusChanged(const QString &pluginName, const QString &message);

    /**
     * @brief 插件操作完成信号
     * @param pluginName 插件名称
     * @param operation 操作名称
     * @param success 是否成功
     * @param result 操作结果
     */
    void pluginOperationCompleted(const QString &pluginName, const QString &operation, bool success, const QVariant &result);

    /**
     * @brief 插件错误信号
     * @param pluginName 插件名称
     * @param error 错误消息
     */
    void pluginError(const QString &pluginName, const QString &error);

private slots:
    /**
     * @brief 处理插件状态变化
     * @param message 状态消息
     * @param progress 进度
     */
    void onPluginStatusChanged(const QString &message, int progress);

    /**
     * @brief 处理插件操作完成
     * @param operation 操作名称
     * @param success 是否成功
     * @param result 操作结果
     */
    void onPluginOperationCompleted(const QString &operation, bool success, const QVariant &result);

private:
    /**
     * @brief 扫描插件目录
     * @return 插件文件路径列表
     */
    QStringList scanPluginsDirectory() const;

    /**
     * @brief 获取插件元数据
     * @param loader 插件加载器
     * @return 元数据映射
     */
    QVariantMap getPluginMetadata(QPluginLoader &loader) const;

    /**
     * @brief 检查插件兼容性
     * @param plugin 插件实例
     * @param metadata 元数据
     * @return 兼容返回true
     */
    bool checkPluginCompatibility(MarkdownPlugin *plugin, const QVariantMap &metadata);

    QString m_pluginsDir;                          // 插件目录
    QStringList m_enabledPlugins;                  // 启用的插件
    QMap<QString, QPluginLoader*> m_pluginLoaders; // 插件加载器映射
    QMap<QString, MarkdownPlugin*> m_plugins;      // 插件实例映射
    QMap<QString, QVariantMap> m_pluginMetadata;   // 插件元数据映射
    QMap<QString, QString> m_pluginPaths;          // 插件路径映射
};

#endif // PLUGINMANAGER_H